// import com.alibaba.druid.sql.ast.SQLExpr;
// import com.alibaba.druid.sql.ast.expr.SQLCharExpr;
// import com.alibaba.druid.sql.ast.expr.SQLMethodInvokeExpr;
// import com.alibaba.druid.sql.visitor.SQLEvalVisitor;

// import java.text.ParseException;
// import java.text.SimpleDateFormat;
// import java.util.List;

// import static com.alibaba.druid.sql.visitor.SQLEvalVisitor.EVAL_ERROR;

#include "ToDate.h"
#include "../SQLEvalVisitor.h"
#include "../../../utils/instanceof.h"
#include "../../ast/expr/SQLCharExpr.h"

ToDate *ToDate::instance()
{
  static ToDate x;
  return &x;
}

Object_ptr ToDate::eval(SQLEvalVisitor *visitor, SQLMethodInvokeExpr *x)
{
  SQLExpr_list_ptr arguments = x->getArguments();
  if (arguments->empty())
  {
    return SQLEvalVisitor::EVAL_ERROR;
  }

  if (arguments->size() == 2)
  {
    auto it_arguments = arguments->begin();
    std::advance(it_arguments, 0);
    auto v0 = *it_arguments;
    std::advance(it_arguments, 1);
    auto v1 = *it_arguments;
    if (instanceof <SQLExpr, SQLCharExpr>(v0) && instanceof <SQLExpr, SQLCharExpr>(v1))
    {
      string_ptr chars = (std::dynamic_pointer_cast<SQLCharExpr>(v0))->getText();
      string_ptr format = (std::dynamic_pointer_cast<SQLCharExpr>(v1))->getText();
      if (format->c_str() == ("yyyymmdd"))
      {
        // SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        // try {
        //     return dateFormat.parse(chars);
        // } catch (ParseException e) {
        //     // skip
        //     return false;
        // }

        time_t date = ((time_t)atol(chars->c_str()));
        std::string myFormat = "%Y%m%d";
        struct tm *myt = localtime(&date);
        char myStr[255] = "\0";
        strftime(myStr, sizeof(myStr), myFormat.c_str(), myt);
        return Object_ptr(new Object(myStr));
      }
    }
  }

  return nullptr;
}
